﻿using System;
using System.Linq;
using Fsxm.LispEdit;
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Threading;
using System.Collections;

[assembly: PluginClass(typeof(Plugin_AutoComment.AutoComment))]


namespace Plugin_AutoComment
{
    public class AutoComment : Plugin
    {
        public override void Start()
        {
            //全部折叠
            var item = AddMenuItem("全部折叠", null);
            item.Click += item_Click;

            //全部展开
            var item2 = AddMenuItem("全部展开", null);
            item2.Click += item2_Click;

            EditApp.DocumentManager.DocumentCreated += DocumentManager_DocumentCreated;


        }



        void DocumentManager_DocumentCreated(object sender, DocumentCollection.DocumentCollectionEventArgs e)
        {
            e.Document.FCTB.KeyDown += Fctb_KeyDown;
        }
        void item_Click(object sender, EventArgs e)
        {
            var edit = ActivateEdit;
            if (edit == null) return;

            edit.CollapseAllFoldingBlocks();
        }

        void item2_Click(object sender, EventArgs e)
        {
            var edit = ActivateEdit;
            if (edit == null) return;

            edit.ExpandAllFoldingBlocks();
        }




        private bool zh() //判断是否为中文系统
        {
            return Thread.CurrentThread.CurrentCulture.Name.Equals("zh-CN", StringComparison.CurrentCultureIgnoreCase);
        }

        private void inserttext(LispTextBox fctb, string text) //插入字符串，并进行缩进处理
        {
            fctb.BeginAutoUndo();
            fctb.Selection.BeginUpdate();
            fctb.BeginUpdate();

            fctb.Selection.Expand();
            var start = fctb.Selection.Start.iLine;
            fctb.InsertText(text);
            int end = fctb.Selection.Start.iLine;
            for (int i = start; i < end; i++)
            {
                fctb.DoAutoIndent(i);
            }
            var po = fctb[start].Count;
            fctb.Selection = new Range(fctb, po, start, po, start);

            fctb.EndAutoUndo();
            fctb.Selection.EndUpdate();
            fctb.EndUpdate();
        }

        private void Fctb_KeyDown(object sender, KeyEventArgs e)
        {
            var fctb = sender as LispTextBox;
            var doc = fctb.Doc;
            string fun_name = zh() ? "\r\n;;;函数名称:{0}" : "\r\n;;;FunName:{0}";
            string desc_value = zh() ? "\r\n;;;函数说明:" : "\r\n;;;FunDesc:";
            string arg_value1 = zh() ? "\r\n;;;参    数:{0}:" : "\r\n;;;arg:{0}:";
            string return_value = zh() ? "\r\n;;;返 回 值:" : "\r\n;;;Return:";
            string exam_value = zh() ? "\r\n;;;示    例:({0} {1})" : "\r\n;;;Example:({0} {1})";
            //函数名称:
            //函数功能:
            //参    数:
            //返 回 值:
            //示    例:
            //string help = string.Empty;
            string arg_value = string.Empty;
            ArrayList examlist = new ArrayList();

            //自动插入注释
            if (e.KeyCode == Keys.OemSemicolon && fctb.Selection.IsEmpty && fctb[fctb.Selection.Start.iLine].Text.Trim() == ";;")
            {
                foreach (var fun in doc.LastRead.DocPublicUsers.Values.Union(doc.LastRead.DocPrivateUsers.Values))
                {
                    if (fun.Location.iLine - 1 != fctb.Selection.Start.iLine)
                    {
                        continue;
                    }
                    e.Handled = true;

                    var node = DocLisp.FindBlock(fun.Location, doc.LastRead.Root);
                    if (node[2].Data.Value.Equals("nil", StringComparison.CurrentCultureIgnoreCase) || (node[2].Count == 0) || (node[2][0].Data.Value == "/"))
                    {
                        arg_value = ""; //如果参数为0或者“ / ”则无参数

                    }
                    else
                    {
                        for (int i = 0; i < node[2].Count; i++) //遍历形参
                        {
                            string arg = node[2][i].Data.Value;
                            if (arg == "/")
                            {
                                break;
                            }
                            arg_value += string.Format(arg_value1, arg);
                            examlist.Add(arg);
                        }
                    }
                    //如果是命令函数（C:XX），则无返回值
                    if (fun.Name.StartsWith("c:", StringComparison.CurrentCultureIgnoreCase))
                    {
                        return_value = "";
                    }



                    fun_name = string.Format(fun_name, fun.Name);
                    exam_value = string.Format(exam_value, fun.Name, string.Join(" ", (string[])examlist.ToArray(typeof(string))));

                    //help = fun_name + desc_value + arg_value + return_value + exam_value;
                    inserttext(fctb, fun_name + desc_value + arg_value + return_value + exam_value);
                    break;
                }
            }

            //单行注释
            if (e.KeyCode == Keys.OemSemicolon)
            {
                if (!fctb.Selection.IsEmpty)
                {
                    e.Handled = true;
                    fctb.CommentSelected();
                    return;
                }
            }
            //块注释
            if (!fctb.Selection.IsEmpty && e.KeyCode == (Keys.OemPipe) && e.Shift)
            {
                e.Handled = true;
                doc.CommentBlock();
                return;
            }

        }

    }
}
